home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / ImageMagick / convert.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  36KB  |  1,045 lines

  1. /*
  2. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3. %                                                                             %
  4. %                                                                             %
  5. %                                                                             %
  6. %                CCCC   OOO   N   N  V   V  EEEEE  RRRR   TTTTT               %
  7. %               C      O   O  NN  N  V   V  E      R   R    T                 %
  8. %               C      O   O  N N N  V   V  EEE    RRRR     T                 %
  9. %               C      O   O  N  NN   V V   E      R R      T                 %
  10. %                CCCC   OOO   N   N    V    EEEEE  R  R     T                 %
  11. %                                                                             %
  12. %                                                                             %
  13. %                Convert an image from one format to another.                 %
  14. %                                                                             %
  15. %                                                                             %
  16. %                                                                             %
  17. %                              Software Design                                %
  18. %                                John Cristy                                  %
  19. %                                April 1992                                   %
  20. %                                                                             %
  21. %                                                                             %
  22. %  Copyright 1994 E. I. Dupont de Nemours & Company                           %
  23. %                                                                             %
  24. %  Permission to use, copy, modify, distribute, and sell this software and    %
  25. %  its documentation for any purpose is hereby granted without fee,           %
  26. %  provided that the above Copyright notice appear in all copies and that     %
  27. %  both that Copyright notice and this permission notice appear in            %
  28. %  supporting documentation, and that the name of E. I. Dupont de Nemours     %
  29. %  & Company not be used in advertising or publicity pertaining to            %
  30. %  distribution of the software without specific, written prior               %
  31. %  permission.  E. I. Dupont de Nemours & Company makes no representations    %
  32. %  about the suitability of this software for any purpose.  It is provided    %
  33. %  "as is" without express or implied warranty.                               %
  34. %                                                                             %
  35. %  E. I. Dupont de Nemours & Company disclaims all warranties with regard     %
  36. %  to this software, including all implied warranties of merchantability      %
  37. %  and fitness, in no event shall E. I. Dupont de Nemours & Company be        %
  38. %  liable for any special, indirect or consequential damages or any           %
  39. %  damages whatsoever resulting from loss of use, data or profits, whether    %
  40. %  in an action of contract, negligence or other tortuous action, arising     %
  41. %  out of or in connection with the use or performance of this software.      %
  42. %                                                                             %
  43. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  44. %
  45. %  Convert converts an input file using one image format to an output file
  46. %  with a differing image format.
  47. %
  48. %  The convert program syntax is:
  49. %
  50. %  Usage: convert [options ...] input_file output_file
  51. %
  52. %  Where options include:
  53. %    -alpha               store alpha channel if the image has one
  54. %    -border geometry     surround image with a border of color
  55. %    -colors value        preferred number of colors in the image
  56. %    -clip geometry       preferred size and location of the clipped image
  57. %    -colorspace type     GRAY, OHTA, RGB, XYZ, YCbCr, YIQ, or YUV
  58. %    -comment string      annotate image with comment
  59. %    -compress type       RunlengthEncoded or QEncoded
  60. %    -density geometry    vertical and horizontal density of the image
  61. %    -display server      obtain image or font from this X server
  62. %    -dither              apply Floyd/Steinberg error diffusion to image
  63. %    -enhance             apply a digital filter to enhance a noisy image
  64. %    -font name           X11 font for displaying text
  65. %    -gamma value         level of gamma correction
  66. %    -geometry geometry   width and height of the image
  67. %    -interlace type      NONE, LINE, or PLANE
  68. %    -inverse             apply color inversion to image
  69. %    -label name          assign a label to an image
  70. %    -monochrome          transform image to black and white
  71. %    -noise               reduce noise with a noise peak elimination filter
  72. %    -normalize           transform image to span the full range of colors
  73. %    -page geometry       size and location of the Postscript page
  74. %    -quality value       JPEG quality setting
  75. %    -reflect             reverse image scanlines
  76. %    -roll geometry       roll an image vertically or horizontally
  77. %    -rotate degrees      apply Paeth rotation to the image
  78. %    -scene value         image scene number
  79. %    -shear geometry      slide one edge of the image along the X or Y axis
  80. %    -treedepth value     depth of the color classification tree
  81. %    -undercolor geometry control undercolor removal and black generation
  82. %    -verbose             print detailed information about the image
  83. %
  84. %  Change '-' to '+' in any option above to reverse its effect.  For
  85. %  example,  specify +alpha to store the image without its alpha channel.
  86. %
  87. %  By default, the image format of `file' is determined by its magic
  88. %  number.  To specify a particular image format, precede the filename
  89. %  with an image format name and a colon (i.e. ps:image) or specify the
  90. %  image type as the filename suffix (i.e. image.ps).  Specify 'file' as
  91. %  '-' for standard input or output.
  92. %
  93. %  Convert recognizes the following image formats:
  94. %
  95. %    Tag   Description
  96. %    ---------------------------------------------------
  97. %    ALPHA Raw alpha bytes.
  98. %    AVS   AVS X image file.
  99. %    BMP   Microsoft Windows bitmap image file.
  100. %    CMYK  Raw cyan, magenta, yellow, and black bytes.
  101. %    EPS   Adobe Encapsulated PostScript file.
  102. %    EPSF  Adobe Encapsulated PostScript file.
  103. %    EPSI  Adobe Encapsulated PostScript Interchange format.
  104. %    FAX   Group 3.
  105. %    FITS  Flexible Image Transport System.
  106. %    GIF   Compuserve Graphics image file.
  107. %    GIF87 Compuserve Graphics image file (version 87a).
  108. %    GRAY  Raw gray bytes.
  109. %    HISTOGRAM
  110. %    IRIS  SGI RGB image file.
  111. %    JPEG
  112. %    MAP   colormap intensities and indices
  113. %    MIFF  Magick image file format.
  114. %    MTV
  115. %    PCD   Photo CD
  116. %    PCX   ZSoft IBM PC Paintbrush file
  117. %    PICT  Apple Macintosh QuickDraw/PICT file.
  118. %    PNM   Portable bitmap.
  119. %    PS    Adobe PostScript file.
  120. %    PS2   Adobe Level II PostScript file.
  121. %    RGB   Raw red, green, and blue bytes.
  122. %    RLE   Utah Run length encoded image file; read only.
  123. %    SUN   SUN Rasterfile.
  124. %    TEXT  raw text file; read only.
  125. %    TGA   Truevision Targa image file.
  126. %    TIFF  Tagged Image File Format.
  127. %    VICAR read only.
  128. %    VIFF  Khoros Visualization image file.
  129. %    X     select image from X server screen.
  130. %    XC    constant image of X server color.
  131. %    XBM   X11 bitmap file.
  132. %    XPM   X11 pixmap file.
  133. %    XWD   X Window System window dump image file.
  134. %    YUV   CCIR 601 1:1:1 file.
  135. %    YUV3  CCIR 601 2:1:1 files.
  136. %
  137. %
  138. */
  139.  
  140. #include "magick.h"
  141. #include "image.h"
  142. #include "X.h"
  143.  
  144. /*
  145. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  146. %                                                                             %
  147. %                                                                             %
  148. %                                                                             %
  149. %   U s a g e                                                                 %
  150. %                                                                             %
  151. %                                                                             %
  152. %                                                                             %
  153. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  154. %
  155. %  Procedure Usage displays the program usage;
  156. %
  157. %  The format of the Usage routine is:
  158. %
  159. %      Usage()
  160. %
  161. %
  162. */
  163. static void Usage()
  164. {
  165.   char
  166.     **p;
  167.  
  168.   static char
  169.     *ImageTypes[]=
  170.     {
  171.       "Tag   Description",
  172.       "------------------------------------------------------------",
  173.       "ALPHA Raw alpha bytes.",
  174.       "AVS   AVS X image file.",
  175.       "BMP   Microsoft Windows bitmap image file.",
  176.       "CMYK  Raw cyan, magenta, yellow, and black bytes.",
  177.       "EPS   Adobe Encapsulated PostScript file.",
  178.       "EPSF  Adobe Encapsulated PostScript file.",
  179.       "EPSI  Adobe Encapsulated PostScript Interchange format.",
  180.       "FAX   Group 3.",
  181.       "FITS  Flexible Image Transport System.",
  182.       "GIF   Compuserve Graphics image file.",
  183.       "GIF87 Compuserve Graphics image file (version 87a).",
  184.       "GRAY  Raw gray bytes.",
  185.       "HISTOGRAM",
  186.       "IRIS  SGI RGB image file.",
  187.       "JPEG",
  188.       "MAP   colormap intensities and indices.",
  189.       "MIFF  Magick image file format.",
  190.       "MTV",
  191.       "PCD   Photo CD.",
  192.       "PCX   ZSoft IBM PC Paintbrush file.",
  193.       "PICT  Apple Macintosh QuickDraw/PICT file.",
  194.       "PNM   Portable bitmap.",
  195.       "PS    Adobe PostScript file.",
  196.       "PS2   Adobe Level II PostScript file.",
  197.       "RGB   Raw red, green, and blue bytes.",
  198.       "RLE   Utah Run length encoded image file; read only.",
  199.       "SUN   SUN Rasterfile.",
  200.       "TEXT  raw text file; read only.",
  201.       "TGA   Truevision Targa image file.",
  202.       "TIFF  Tagged Image File Format.",
  203.       "VICAR read only.",
  204.       "VIFF  Khoros Visualization image file.",
  205.       "X     select image from X server screen.",
  206.       "XC    constant image of X server color.",
  207.       "XBM   X11 bitmap file.",
  208.       "XPM   X11 pixmap file.",
  209.       "XWD   X Window System window dump image file.",
  210.       "YUV   CCIR 601 1:1:1 file.",
  211.       "YUV3  CCIR 601 2:1:1 files.",
  212.       (char *) NULL,
  213.     },
  214.     *options[]=
  215.     {
  216.       "-alpha               store alpha channel if the image has one",
  217.       "-border geometry     surround image with a border of color",
  218.       "-clip geometry       preferred size and location of the clipped image",
  219.       "-colors value        preferred number of colors in the image",
  220.       "-colorspace type     GRAY, OHTA, RGB, XYZ, YCbCr, YIQ, or YUV",
  221.       "-comment string      annotate image with comment",
  222.       "-compress type       RunlengthEncoded or QEncoded",
  223.       "-density geometry    vertical and horizontal density of the image",
  224.       "-display server      obtain image or font from this X server",
  225.       "-dither              apply Floyd/Steinberg error diffusion to image",
  226.       "-enhance             apply a digital filter to enhance a noisy image",
  227.       "-font name           X11 font for displaying text",
  228.       "-gamma value         level of gamma correction",
  229.       "-geometry geometry   width and height of the image",
  230.       "-interlace type      NONE, LINE, or PLANE",
  231.       "-inverse             apply color inversion to image",
  232.       "-label name          assign a label to an image",
  233.       "-monochrome          transform image to black and white",
  234.       "-noise               reduce noise with a noise peak elimination filter",
  235.       "-normalize           transform image to span the full range of colors",
  236.       "-page geometry       size and location of the Postscript page",
  237.       "-quality value       JPEG quality setting",
  238.       "-reflect             reverse image scanlines",
  239.       "-roll geometry       roll an image vertically or horizontally",
  240.       "-rotate degrees      apply Paeth rotation to the image",
  241.       "-scene value         image scene number",
  242.       "-shear geometry      slide one edge of the image along the X or Y axis",
  243.       "-treedepth value     depth of the color classification tree",
  244.       "-undercolor geometry control undercolor removal and black generation",
  245.       "-verbose             print detailed information about the image",
  246.       (char *) NULL
  247.     };
  248.   (void) fprintf(stderr,"Usage: %s [options ...] input_file output_file\n",
  249.     client_name);
  250.   (void) fprintf(stderr,"\nWhere options include:\n");
  251.   for (p=options; *p != (char *) NULL; p++)
  252.     (void) fprintf(stderr,"  %s\n",*p);
  253.   (void) fprintf(stderr,
  254.     "\nChange '-' to '+' in any option above to reverse its effect.  For\n");
  255.   (void) fprintf(stderr,
  256.     "example,  specify +alpha to store the image without an alpha channel.\n");
  257.   (void) fprintf(stderr,
  258.     "\nBy default, the image format of `file' is determined by its magic\n");
  259.   (void) fprintf(stderr,
  260.     "number.  To specify a particular image format, precede the filename\n");
  261.   (void) fprintf(stderr,
  262.     "with an image format name and a colon (i.e. ps:image) or specify the\n");
  263.   (void) fprintf(stderr,
  264.     "image type as the filename suffix (i.e. image.ps).  Specify 'file' as\n");
  265.   (void) fprintf(stderr,"'-' for standard input or output.\n");
  266.   (void) fprintf(stderr,"\nThe following image formats are recognized: \n\n");
  267.   for (p=ImageTypes; *p != (char *) NULL; p++)
  268.     (void) fprintf(stderr,"  %s\n",*p);
  269.   exit(1);
  270. }
  271.  
  272. /*
  273. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  274. %                                                                             %
  275. %                                                                             %
  276. %                                                                             %
  277. %  M a i n                                                                    %
  278. %                                                                             %
  279. %                                                                             %
  280. %                                                                             %
  281. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  282. %
  283. %
  284. */
  285. int main(argc,argv)
  286. int
  287.   argc;
  288.  
  289. char
  290.   *argv[];
  291. {
  292. #define NotInitialized  (unsigned int) (~0)
  293.  
  294.   char
  295.     *border_color,
  296.     *comment,
  297.     *density,
  298.     *filename,
  299.     *font,
  300.     *label,
  301.     *image_geometry,
  302.     *option,
  303.     *page_geometry,
  304.     *server_name,
  305.     *undercolor_geometry;
  306.  
  307.   double
  308.     normalized_maximum_error,
  309.     normalized_mean_error;
  310.  
  311.   Image
  312.     *image,
  313.     *next_image;
  314.  
  315.   ImageInfo
  316.     image_info;
  317.  
  318.   int
  319.     flags,
  320.     status,
  321.     x,
  322.     y;
  323.  
  324.   register int
  325.     i;
  326.  
  327.   time_t
  328.     start_time;
  329.  
  330.   unsigned int
  331.     alpha,
  332.     colorspace,
  333.     compression,
  334.     dither,
  335.     height,
  336.     interlace,
  337.     monochrome,
  338.     mean_error_per_pixel,
  339.     number_colors,
  340.     quality,
  341.     scene,
  342.     tree_depth,
  343.     verbose,
  344.     width;
  345.  
  346.   unsigned long
  347.     total_colors;
  348.  
  349.   /*
  350.     Initialize program variables.
  351.   */
  352.   client_name=argv[0];
  353.   if (argc < 3)
  354.     Usage();
  355.   /*
  356.     Read image and convert to MIFF format.
  357.   */
  358.   alpha=NotInitialized;
  359.   border_color=(char *) NULL;
  360.   colorspace=RGBColorspace;
  361.   compression=UndefinedCompression;
  362.   comment=(char *) NULL;
  363.   density=(char *) NULL;
  364.   dither=False;
  365.   font=(char *) NULL;
  366.   image=(Image *) NULL;
  367.   image_geometry=(char *) NULL;
  368.   interlace=NoneInterlace;
  369.   label=(char *) NULL;
  370.   monochrome=False;
  371.   number_colors=0;
  372.   page_geometry=(char *) NULL;
  373.   quality=85;
  374.   scene=0;
  375.   server_name=(char *) NULL;
  376.   start_time=time((time_t *) NULL);
  377.   tree_depth=0;
  378.   undercolor_geometry=(char *) NULL;
  379.   verbose=False;
  380.   /*
  381.     Check command syntax.
  382.   */
  383.   filename=(char *) NULL;
  384.   for (i=1; i < (argc-1); i++)
  385.   {
  386.     option=argv[i];
  387.     if (((int) strlen(option) < 2) || ((*option != '-') && (*option != '+')))
  388.       {
  389.         /*
  390.           Read input image.
  391.         */
  392.         filename=argv[i];
  393.         GetImageInfo(filename,&image_info);
  394.         image_info.server_name=server_name;
  395.         image_info.font=font;
  396.         image_info.geometry=image_geometry;
  397.         image_info.page=page_geometry;
  398.         image_info.density=density;
  399.         image_info.interlace=interlace;
  400.         image_info.monochrome=monochrome;
  401.         image_info.quality=quality;
  402.         image_info.verbose=verbose;
  403.         image_info.undercolor=undercolor_geometry;
  404.         if (image != (Image *) NULL)
  405.           Error("input image already specified",filename);
  406.         image=ReadImage(&image_info);
  407.         if (image == (Image *) NULL)
  408.           exit(1);
  409.       }
  410.     else
  411.       switch(*(option+1))
  412.       {
  413.         case 'a':
  414.         {
  415.           alpha=(*option == '-');
  416.           break;
  417.         }
  418.         case 'b':
  419.         {
  420.           if (strncmp("border",option+1,7) == 0)
  421.             {
  422.               if (*option == '-')
  423.                 {
  424.                   i++;
  425.                   if (i == argc)
  426.                     Error("Missing geometry on -border",(char *) NULL);
  427.                 }
  428.               break;
  429.             }
  430.           if (strncmp("bordercolor",option+1,7) == 0)
  431.             {
  432.               border_color=(char *) NULL;
  433.               if (*option == '-')
  434.                 {
  435.                   i++;
  436.                   if (i == argc)
  437.                     Error("Missing color on -bordercolor",(char *) NULL);
  438.                   border_color=argv[i];
  439.                 }
  440.               break;
  441.             }
  442.           Error("Unrecognized option",option);
  443.           break;
  444.         }
  445.         case 'c':
  446.         {
  447.           if (strncmp("clip",option+1,2) == 0)
  448.             {
  449.               if (*option == '-')
  450.                 {
  451.                   i++;
  452.                   if ((i == argc) || !sscanf(argv[i],"%d",&x))
  453.                     Error("Missing geometry on -clip",(char *) NULL);
  454.                 }
  455.               break;
  456.             }
  457.           if (strncmp("colors",option+1,7) == 0)
  458.             {
  459.               number_colors=0;
  460.               if (*option == '-')
  461.                 {
  462.                   i++;
  463.                   if ((i == argc) || !sscanf(argv[i],"%d",&x))
  464.                     Error("Missing colors on -colors",(char *) NULL);
  465.                   number_colors=atoi(argv[i]);
  466.                 }
  467.               break;
  468.             }
  469.           if (strncmp("colorspace",option+1,7) == 0)
  470.             {
  471.               colorspace=RGBColorspace;
  472.               if (*option == '-')
  473.                 {
  474.                   i++;
  475.                   if (i == argc)
  476.                     Error("Missing type on -colorspace",(char *) NULL);
  477.                   option=argv[i];
  478.                   colorspace=UndefinedColorspace;
  479.                   if (Latin1Compare("gray",option) == 0)
  480.                     {
  481.                       colorspace=GRAYColorspace;
  482.                       number_colors=256;
  483.                       tree_depth=8;
  484.                     }
  485.                   if (Latin1Compare("ohta",option) == 0)
  486.                     colorspace=OHTAColorspace;
  487.                   if (Latin1Compare("rgb",option) == 0)
  488.                     colorspace=RGBColorspace;
  489.                   if (Latin1Compare("xyz",option) == 0)
  490.                     colorspace=XYZColorspace;
  491.                   if (Latin1Compare("ycbcr",option) == 0)
  492.                     colorspace=YCbCrColorspace;
  493.                   if (Latin1Compare("yiq",option) == 0)
  494.                     colorspace=YIQColorspace;
  495.                   if (Latin1Compare("yuv",option) == 0)
  496.                     colorspace=YUVColorspace;
  497.                   if (colorspace == UndefinedColorspace)
  498.                     Error("Invalid colorspace type on -colorspace",option);
  499.                 }
  500.               break;
  501.             }
  502.           if (strncmp("comment",option+1,4) == 0)
  503.             {
  504.               comment=(char *) NULL;
  505.               if (*option == '-')
  506.                 {
  507.                   i++;
  508.                   if (i == argc)
  509.                     Error("Missing comment on -comment",(char *) NULL);
  510.                   comment=argv[i];
  511.                 }
  512.               break;
  513.             }
  514.           if (strncmp("compress",option+1,4) == 0)
  515.             {
  516.               compression=NoCompression;
  517.               if (*option == '-')
  518.                 {
  519.                   i++;
  520.                   if (i == argc)
  521.                     Error("Missing type on -compress",(char *) NULL);
  522.                   option=argv[i];
  523.                   if (Latin1Compare("runlengthencoded",option) == 0)
  524.                     compression=RunlengthEncodedCompression;
  525.                   else
  526.                     if (Latin1Compare("qencoded",option) == 0)
  527.                       compression=QEncodedCompression;
  528.                     else
  529.                       Error("Invalid compression type on -compress",option);
  530.                 }
  531.               break;
  532.             }
  533.           Error("Unrecognized option",option);
  534.           break;
  535.         }
  536.         case 'd':
  537.         {
  538.           if (strncmp("density",option+1,3) == 0)
  539.             {
  540.               density=(char *) NULL;
  541.               if (*option == '-')
  542.                 {
  543.                   i++;
  544.                   if ((i == argc) || !sscanf(argv[i],"%d",&x))
  545.                     Error("Missing geometry on -density",(char *) NULL);
  546.                   density=argv[i];
  547.                 }
  548.               break;
  549.             }
  550.           if (strncmp("display",option+1,3) == 0)
  551.             {
  552.               server_name=(char *) NULL;
  553.               if (*option == '-')
  554.                 {
  555.                   i++;
  556.                   if (i == argc)
  557.                     Error("Missing server name on -display",(char *) NULL);
  558.                   server_name=argv[i];
  559.                 }
  560.               break;
  561.             }
  562.           if (strncmp("dither",option+1,3) == 0)
  563.             {
  564.               dither=(*option == '-');
  565.               break;
  566.             }
  567.           Error("Unrecognized option",option);
  568.           break;
  569.         }
  570.         case 'e':
  571.         {
  572.           if (strncmp("enhance",option+1,1) == 0)
  573.             break;
  574.           Error("Unrecognized option",option);
  575.           break;
  576.         }
  577.         case 'f':
  578.         {
  579.           font=(char *) NULL;
  580.           if (*option == '-')
  581.             {
  582.               i++;
  583.               if (i == argc)
  584.                 Error("Missing font name on -font",(char *) NULL);
  585.               font=argv[i];
  586.             }
  587.           break;
  588.         }
  589.         case 'g':
  590.         {
  591.           if (strncmp("gamma",option+1,2) == 0)
  592.             {
  593.               if (*option == '-')
  594.                 {
  595.                   i++;
  596.                   if ((i == argc) || !sscanf(argv[i],"%f",(float *) &x))
  597.                     Error("Missing value on -gamma",(char *) NULL);
  598.                 }
  599.               break;
  600.             }
  601.           if (strncmp("geometry",option+1,2) == 0)
  602.             {
  603.               image_geometry=(char *) NULL;
  604.               if (*option == '-')
  605.                 {
  606.                   i++;
  607.                   if ((i == argc) || !sscanf(argv[i],"%d",&x))
  608.                     Error("Missing geometry on -geometry",(char *) NULL);
  609.                   image_geometry=argv[i];
  610.                 }
  611.               break;
  612.             }
  613.           Error("Unrecognized option",option);
  614.           break;
  615.         }
  616.         case 'h':
  617.         {
  618.           Usage();
  619.           break;
  620.         }
  621.         case 'i':
  622.         {
  623.           if (strncmp("interlace",option+1,3) == 0)
  624.             {
  625.               interlace=NoneInterlace;
  626.               if (*option == '-')
  627.                 {
  628.                   i++;
  629.                   if (i == argc)
  630.                     Error("Missing type on -interlace",(char *) NULL);
  631.                   option=argv[i];
  632.                   interlace=UndefinedInterlace;
  633.                   if (Latin1Compare("none",option) == 0)
  634.                     interlace=NoneInterlace;
  635.                   if (Latin1Compare("line",option) == 0)
  636.                     interlace=LineInterlace;
  637.                   if (Latin1Compare("plane",option) == 0)
  638.                     interlace=PlaneInterlace;
  639.                   if (interlace == UndefinedInterlace)
  640.                     Error("Invalid interlace type on -interlace",option);
  641.                 }
  642.               break;
  643.             }
  644.           if (strncmp("inverse",option+1,3) == 0)
  645.             break;
  646.           Error("Unrecognized option",option);
  647.         }
  648.         case 'l':
  649.         {
  650.           if (strncmp("label",option+1,2) == 0)
  651.             {
  652.               label=(char *) NULL;
  653.               if (*option == '-')
  654.                 {
  655.                   i++;
  656.                   if (i == argc)
  657.                     Error("Missing label name on -label",(char *) NULL);
  658.                   label=argv[i];
  659.                 }
  660.               break;
  661.             }
  662.           Error("Unrecognized option",option);
  663.           break;
  664.         }
  665.         case 'm':
  666.         {
  667.           if (strncmp("monochrome",option+1,2) == 0)
  668.             {
  669.               monochrome=(*option == '-');
  670.               if (monochrome)
  671.                 {
  672.                   number_colors=2;
  673.                   tree_depth=8;
  674.                   colorspace=GRAYColorspace;
  675.                 }
  676.               break;
  677.             }
  678.           Error("Unrecognized option",option);
  679.         }
  680.         case 'n':
  681.         {
  682.           if (strncmp("noise",option+1,3) == 0)
  683.             break;
  684.           if (strncmp("normalize",option+1,3) == 0)
  685.             break;
  686.           Error("Unrecognized option",option);
  687.           break;
  688.         }
  689.         case 'p':
  690.         {
  691.           if (strncmp("page",option+1,2) == 0)
  692.             {
  693.               page_geometry=(char *) NULL;
  694.               if (*option == '-')
  695.                 {
  696.                   i++;
  697.                   if ((i == argc) || !sscanf(argv[i],"%d",&x))
  698.                     Error("Missing page geometry on -page",(char *) NULL);
  699.                   page_geometry=argv[i];
  700.                 }
  701.               break;
  702.             }
  703.           Error("Unrecognized option",option);
  704.           break;
  705.         }
  706.         case 'q':
  707.         {
  708.           i++;
  709.           if ((i == argc) || !sscanf(argv[i],"%d",&x))
  710.             Error("Missing quality on -quality",(char *) NULL);
  711.           quality=atoi(argv[i]);
  712.           break;
  713.         }
  714.         case 'r':
  715.         {
  716.           if (strncmp("reflect",option+1,2) == 0)
  717.             break;
  718.           if (strncmp("roll",option+1,3) == 0)
  719.             {
  720.               if (*option == '-')
  721.                 {
  722.                   i++;
  723.                   if ((i == argc) || !sscanf(argv[i],"%d",&x))
  724.                     Error("Missing geometry on -roll",(char *) NULL);
  725.                 }
  726.               break;
  727.             }
  728.           if (strncmp("rotate",option+1,3) == 0)
  729.             {
  730.               if (*option == '-')
  731.                 {
  732.                   i++;
  733.                   if ((i == argc) || !sscanf(argv[i],"%f",(float *) &x))
  734.                     Error("Missing degrees on -rotate",(char *) NULL);
  735.                 }
  736.               break;
  737.             }
  738.           Error("Unrecognized option",option);
  739.           break;
  740.         }
  741.         case 's':
  742.         {
  743.           if (strncmp("scene",option+1,3) == 0)
  744.             {
  745.               scene=0;
  746.               if (*option == '-')
  747.                 {
  748.                   i++;
  749.                   if ((i == argc) || !sscanf(argv[i],"%d",&x))
  750.                     Error("Missing scene number on -scene",(char *) NULL);
  751.                   scene=atoi(argv[i]);
  752.                 }
  753.               break;
  754.             }
  755.           if (strncmp("shear",option+1,2) == 0)
  756.             {
  757.               if (*option == '-')
  758.                 {
  759.                   i++;
  760.                   if ((i == argc) || !sscanf(argv[i],"%f",(float *) &x))
  761.                     Error("Missing shear geometry on -shear",(char *) NULL);
  762.                 }
  763.               break;
  764.             }
  765.           Error("Unrecognized option",option);
  766.           break;
  767.         }
  768.         case 't':
  769.         {
  770.           tree_depth=0;
  771.           if (*option == '-')
  772.             {
  773.               i++;
  774.               if ((i == argc) || !sscanf(argv[i],"%d",&x))
  775.                 Error("Missing depth on -treedepth",(char *) NULL);
  776.               tree_depth=atoi(argv[i]);
  777.             }
  778.           break;
  779.         }
  780.         case 'u':
  781.         {
  782.           if (strncmp("undercolor",option+1,2) == 0)
  783.             {
  784.               undercolor_geometry=(char *) NULL;
  785.               if (*option == '-')
  786.                 {
  787.                   i++;
  788.                   if ((i == argc) || !sscanf(argv[i],"%f",(float *) &x))
  789.                     Error("Missing undercolor geometry on -undercolor",
  790.                       (char *) NULL);
  791.                   undercolor_geometry=argv[i];
  792.                 }
  793.               break;
  794.             }
  795.           Error("Unrecognized option",option);
  796.           break;
  797.         }
  798.         case 'v':
  799.         {
  800.           if (strncmp("verbose",option+1,1) == 0)
  801.             {
  802.               verbose=(*option == '-');
  803.               break;
  804.             }
  805.           Error("Unrecognized option",option);
  806.           break;
  807.         }
  808.         default:
  809.         {
  810.           Error("Unrecognized option",option);
  811.           break;
  812.         }
  813.       }
  814.   }
  815.   if (image == (Image *) NULL)
  816.     Error("Missing an image file name",(char *) NULL);
  817.   /*
  818.     Write images.
  819.   */
  820.   do
  821.   {
  822.     total_colors=0;
  823.     if (alpha != NotInitialized)
  824.       image->alpha=alpha;
  825.     if (compression != UndefinedCompression)
  826.       image->compression=compression;
  827.     if (scene != 0)
  828.       image->scene=scene;
  829.     LabelImage(image,label);
  830.     if (comment != (char *) NULL)
  831.       CommentImage(image,comment);
  832.     (void) strcpy(image->filename,argv[i]);
  833.     /*
  834.       Transform image as defined by the image geometries.
  835.     */
  836.     for (i=1; i < (argc-1); i++)
  837.     {
  838.       option=argv[i];
  839.       if (strncmp("-border",option,8) == 0)
  840.         {
  841.           Image
  842.             *bordered_image;
  843.  
  844.           ImageInfo
  845.             border_info;
  846.  
  847.           /*
  848.             Surround image with a border of solid color.
  849.           */
  850.           i++;
  851.           border_info=image_info;
  852.           (void) strcpy(border_info.filename,"XC:");
  853.           if (border_color != (char *) NULL)
  854.             (void) strcat(border_info.filename,border_color);
  855.           border_info.geometry="1x1";
  856.           bordered_image=ReadImage(&border_info);
  857.           if (bordered_image != (Image *) NULL)
  858.             {
  859.               ColorPacket
  860.                 border_color;
  861.  
  862.               RectangleInfo
  863.                 border_info;
  864.  
  865.               DestroyImage(bordered_image);
  866.               border_info.width=0;
  867.               border_info.height=0;
  868.               border_info.x=0;
  869.               border_info.y=0;
  870.               flags=XParseGeometry(argv[i],&border_info.x,&border_info.y,
  871.                 &border_info.width,&border_info.height);
  872.               if ((flags & HeightValue) == 0)
  873.                 border_info.height=border_info.width;
  874.               border_color.red=bordered_image->pixels->red;
  875.               border_color.green=bordered_image->pixels->green;
  876.               border_color.blue=bordered_image->pixels->blue;
  877.               bordered_image=
  878.                 BorderImage(image,&border_info,&border_color,&border_color);
  879.               if (bordered_image != (Image *) NULL)
  880.                 {
  881.                   DestroyImage(image);
  882.                   bordered_image->class=DirectClass;
  883.                   image=bordered_image;
  884.                 }
  885.             }
  886.         }
  887.       if (strncmp("-clip",option,3) == 0)
  888.         TransformImage(&image,argv[++i],(char *) NULL);
  889.       if (strncmp("-enhance",option,2) == 0)
  890.         {
  891.           Image
  892.             *enhanced_image;
  893.  
  894.           /*
  895.             Enhance image.
  896.           */
  897.           enhanced_image=EnhanceImage(image);
  898.           if (enhanced_image != (Image *) NULL)
  899.             {
  900.               DestroyImage(image);
  901.               image=enhanced_image;
  902.             }
  903.         }
  904.       if (strncmp("-gamma",option,3) == 0)
  905.         GammaImage(image,argv[++i]);
  906.       if (strncmp("-geometry",option,4) == 0)
  907.         TransformImage(&image,(char *) NULL,argv[++i]);
  908.       if (strncmp("-inverse",option,4) == 0)
  909.         InverseImage(image);
  910.       if (strncmp("-noise",option,4) == 0)
  911.         {
  912.           Image
  913.             *noisy_image;
  914.  
  915.           /*
  916.             Reduce noise in image.
  917.           */
  918.           noisy_image=NoisyImage(image);
  919.           if (noisy_image != (Image *) NULL)
  920.             {
  921.               DestroyImage(image);
  922.               image=noisy_image;
  923.             }
  924.         }
  925.       if (strncmp("-normalize",option,4) == 0)
  926.         NormalizeImage(image);
  927.       if (strncmp("-reflect",option,3) == 0)
  928.         {
  929.           Image
  930.             *reflected_image;
  931.  
  932.           /*
  933.             Reverse image scanlines.
  934.           */
  935.           reflected_image=ReflectImage(image);
  936.           if (reflected_image != (Image *) NULL)
  937.             {
  938.               DestroyImage(image);
  939.               image=reflected_image;
  940.             }
  941.         }
  942.       if (strncmp("-roll",option,4) == 0)
  943.         {
  944.           Image
  945.             *rolled_image;
  946.  
  947.           /*
  948.             Roll image.
  949.           */
  950.           x=0;
  951.           y=0;
  952.           flags=XParseGeometry(argv[++i],&x,&y,&width,&height);
  953.           rolled_image=RollImage(image,x,y);
  954.           if (rolled_image != (Image *) NULL)
  955.             {
  956.               DestroyImage(image);
  957.               image=rolled_image;
  958.             }
  959.         }
  960.       if (strncmp("-rotate",option,4) == 0)
  961.         {
  962.           Image
  963.             *rotated_image;
  964.  
  965.           /*
  966.             Rotate image.
  967.           */
  968.           rotated_image=RotateImage(image,(double) atof(argv[++i]),False);
  969.           if (rotated_image != (Image *) NULL)
  970.             {
  971.               DestroyImage(image);
  972.               image=rotated_image;
  973.             }
  974.         }
  975.       if (strncmp("-shear",option,3) == 0)
  976.         {
  977.           float
  978.             x_shear,
  979.             y_shear;
  980.  
  981.           Image
  982.             *sheared_image;
  983.  
  984.           /*
  985.             Shear image.
  986.           */
  987.           x_shear=0.0;
  988.           y_shear=0.0;
  989.           (void) sscanf(argv[++i],"%fx%f",&x_shear,&y_shear);
  990.           sheared_image=ShearImage(image,x_shear,y_shear,False);
  991.           if (sheared_image != (Image *) NULL)
  992.             {
  993.               DestroyImage(image);
  994.               image=sheared_image;
  995.             }
  996.       }
  997.     }
  998.     if (number_colors != 0)
  999.       {
  1000.         /*
  1001.           Reduce the number of colors in the image.
  1002.         */
  1003.         if ((image->class == DirectClass) || (image->colors > number_colors) ||
  1004.             (colorspace == GRAYColorspace))
  1005.           QuantizeImage(image,number_colors,tree_depth,dither,colorspace,True);
  1006.         if (verbose)
  1007.           {
  1008.             /*
  1009.               Measure quantization error.
  1010.             */
  1011.             QuantizationError(image,&mean_error_per_pixel,
  1012.               &normalized_mean_error,&normalized_maximum_error);
  1013.             total_colors=NumberColors(image,(FILE *) NULL);
  1014.           }
  1015.         SyncImage(image);
  1016.       }
  1017.     status=WriteImage(&image_info,image);
  1018.     if (verbose)
  1019.       {
  1020.         /*
  1021.           Display detailed info about the image.
  1022.         */
  1023.         (void) fprintf(stderr,"[%u] %s=>%s %ux%u",image->scene,filename,
  1024.           image->filename,image->columns,image->rows);
  1025.         if (image->class == DirectClass)
  1026.           (void) fprintf(stderr," DirectClass");
  1027.         else
  1028.           if (total_colors == 0)
  1029.             (void) fprintf(stderr," PseudoClass %uc",image->colors);
  1030.           else
  1031.             {
  1032.               (void) fprintf(stderr," PseudoClass %lu=>%uc",total_colors,
  1033.                 image->colors);
  1034.               (void) fprintf(stderr," %u/%.6f/%.6fe",mean_error_per_pixel,
  1035.                 normalized_mean_error,normalized_maximum_error);
  1036.             }
  1037.         (void) fprintf(stderr," %s %lds\n",image->magick,
  1038.           time((time_t *) NULL)-start_time+1);
  1039.       }
  1040.     next_image=image->next;
  1041.     image=next_image;
  1042.   } while (image != (Image *) NULL);
  1043.   return(!status);
  1044. }
  1045.